<script>
    import ElScrollbar from 'element-ui/packages/scrollbar';
    import CascaderNode from './cascader-node.vue';
    import Locale from 'element-ui/src/mixins/locale';
    import {generateId} from 'element-ui/src/utils/util';

    export default {
        name: 'ElCascaderMenu',

        mixins: [Locale],

        inject: ['panel'],

        components: {
            ElScrollbar,
            CascaderNode
        },

        props: {
            nodes: {
                type: Array,
                required: true
            },
            index: Number
        },

        data() {
            return {
                activeNode: null,
                hoverTimer: null,
                id: generateId()
            };
        },

        computed: {
            isEmpty() {
                return !this.nodes.length;
            },
            menuId() {
                return `cascader-menu-${this.id}-${this.index}`;
            }
        },

        methods: {
            handleExpand(e) {
                this.activeNode = e.target;
            },
            handleMouseMove(e) {
                const {activeNode, hoverTimer} = this;
                const {hoverZone} = this.$refs;

                if (!activeNode || !hoverZone) return;

                if (activeNode.contains(e.target)) {
                    clearTimeout(hoverTimer);

                    const {left} = this.$el.getBoundingClientRect();
                    const startX = e.clientX - left;
                    const {offsetWidth, offsetHeight} = this.$el;
                    const top = activeNode.offsetTop;
                    const bottom = top + activeNode.offsetHeight;

                    hoverZone.innerHTML = `
          <path style="pointer-events: auto;" fill="transparent" d="M${startX} ${top} L${offsetWidth} 0 V${top} Z" />
          <path style="pointer-events: auto;" fill="transparent" d="M${startX} ${bottom} L${offsetWidth} ${offsetHeight} V${bottom} Z" />
        `;
                } else if (!hoverTimer) {
                    this.hoverTimer = setTimeout(this.clearHoverZone, this.panel.config.hoverThreshold);
                }
            },
            clearHoverZone() {
                const {hoverZone} = this.$refs;
                if (!hoverZone) return;
                hoverZone.innerHTML = '';
            },

            renderEmptyText(h) {
                return (
                    < div
            class
                = "el-cascader-menu__empty-text" > {this.t('el.cascader.noData')
            }<
                /div>
            )
                ;
            },
            renderNodeList(h) {
                const {menuId} = this;
                const {isHoverMenu} = this.panel;
                const events = {on: {}};

                if (isHoverMenu) {
                    events.on.expand = this.handleExpand;
                }

                const nodes = this.nodes.map((node, index) => {
                    const {hasChildren} = node;
                    return (
                        < cascader - node
                    key = {node.uid
                }
                    node = {node}
                    node - id = {`${menuId}-${index}`
                }
                    aria - haspopup = {hasChildren}
                    aria - owns = {hasChildren ? menuId : null}
                    { ...
                        events
                    }
                ><
                    /cascader-node>
                )
                    ;
                });

                return [
                    ...nodes,
                    isHoverMenu ? < svg
                ref = 'hoverZone'
            class
                = 'el-cascader-menu__hover-zone' > < /svg> : null
            ]
                ;
            }
        },

        render(h) {
            const {isEmpty, menuId} = this;
            const events = {nativeOn: {}};

            // optimize hover to expand experience (#8010)
            if (this.panel.isHoverMenu) {
                events.nativeOn.mousemove = this.handleMouseMove;
                // events.nativeOn.mouseleave = this.clearHoverZone;
            }

            return (
                < el - scrollbar
            tag = "ul"
            role = "menu"
            id = {menuId}
        class
            = "el-cascader-menu"
            wrap - class = "el-cascader-menu__wrap"
            view - class = {
            {
                'el-cascader-menu__list'
            :
                true,
                    'is-empty'
            :
                isEmpty
            }
        }
            { ...
                events
            }
        >
            {
                isEmpty ? this.renderEmptyText(h) : this.renderNodeList(h)
            }
        <
            /el-scrollbar>
        )
            ;
        }
    };
</script>
